<template>
  <div>
    <Upload
      v-bind="$attrs"
      v-model:file-list="fileList"
      :list-type="listType"
      :accept="getStringAccept"
      :multiple="multiple"
      :maxCount="maxNumber"
      :before-upload="beforeUpload"
      :custom-request="customRequest"
      :disabled="disabled"
      @preview="handlePreview"
      @remove="handleRemove"
    >
      <div v-if="fileList && fileList.length < maxNumber && listType !== 'text'">
        <plus-outlined />
        <div style="margin-top: 8px">{{ t('component.upload.upload') }}</div>
      </div>
      <div v-else-if="fileList && fileList.length < maxNumber && listType == 'text'">
        <slot></slot>
      </div>
    </Upload>
    <ImagePreview :imageList="[previewImage]" />
    <!-- <Modal :open="previewOpen" :title="previewTitle" :footer="null" @cancel="handleCancel">
      <img alt="" style="width: 100%" :src="previewImage" />
    </Modal> -->
  </div>
</template>

<script lang="ts" setup>
  import { ref, toRefs, watch } from 'vue';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import type { UploadFile, UploadProps } from 'ant-design-vue';
  //  Modal,
  import { Upload, message } from 'ant-design-vue';
  import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
  import { useMessage } from '@/hooks/web/useMessage';
  // isFunction
  import { isArray, isObject, isString } from '@/utils/is';
  import { useI18n } from '@/hooks/web/useI18n';
  import { useUploadType } from '../hooks/useUpload';
  import { createImgPreview, ImagePreview } from '@/components/Preview';
  import { uploadContainerProps } from '../props';
  import { checkFileType } from '../helper';
  import { UploadResultStatus } from '@/components/Upload/src/types/typing';
  import { get, omit } from 'lodash-es';
  import { uploadApi, delFileApi } from '@/api/escloud/upload';
  import { getFileType, getFileUrl } from '@/utils/common/index';
  // import { getJti } from '@/utils/cookie';
  // import axios from 'axios';

  defineOptions({ name: 'ImageUpload' });

  const emit = defineEmits(['change', 'update:value', 'delete']);
  const props = defineProps({
    ...omit(uploadContainerProps, ['previewColumns', 'beforePreviewData']),
  });
  const { t } = useI18n();
  const { createMessage } = useMessage();
  const { accept, helpText, maxNumber, maxSize } = toRefs(props);
  const isInnerOperate = ref<boolean>(false);
  const { getStringAccept } = useUploadType({
    acceptRef: accept,
    helpTextRef: helpText,
    maxNumberRef: maxNumber,
    maxSizeRef: maxSize,
  });
  // const previewOpen = ref<boolean>(false);
  const previewImage = ref<string>('');
  // const previewTitle = ref<string>('');
  const fileList = ref<UploadProps['fileList']>([]);
  const isLtMsg = ref<boolean>(true);
  const isActMsg = ref<boolean>(true);
  // console.log('v------------------fileList', fileList);

  watch(
    () => props.value,
    (v) => {
      // console.log('🚀 ~ v:', v, isInnerOperate.value);
      if (isInnerOperate.value) {
        isInnerOperate.value = false;
        return;
      }
      let value: string[] = [];
      if (v) {
        if (isArray(v)) {
          value = v;
        } else {
          value.push(v);
        }
        // const token = getJti();
        console.log('watch-value', value);
        fileList.value = value.map((item: any, i) => {
          if (item && isString(item)) {
            return {
              uid: -i + '',
              name: item.substring(item.lastIndexOf('/') + 1),
              status: 'done',
              url: item,
            };
          } else if (item && isObject(item)) {
            return {
              ...item,
              value: item.value,
              // url: fetchFiles(item.url),
            };
          } else {
            return;
          }
        }) as UploadProps['fileList'];

        console.log('fileList', fileList.value);
      }
      emit('update:value', value);
      // emit('change', value);
      // console.log('🚀 ~ fileList.value=value.map ~ fileList:', fileList);
    },
    {
      immediate: true,
      deep: true,
    },
  );

  // 供应商资质附件需要通过接口来获取
  // async function fetchFiles(url: string) {
  //   const { uploadParams = {} } = props;
  //   if (uploadParams.configCode == 'es1688_member_certificate') {
  //     const token = getJti();
  //     console.log('fetchFiles-url', url);
  //     console.log('fetchFiles-token', token);
  //     const res = await axios.get(`${url}?isAdmin=true`, {
  //       headers: {
  //         Authorization: `jti_${token}`,
  //       },
  //       responseType: 'blob',
  //     });
  //     console.log('fetchFiles-res', res);
  //     const urlData = URL.createObjectURL(res.data);
  //     console.log('fetchFiles-url', urlData);
  //     return urlData;
  //   } else {
  //     return url;
  //   }
  // }

  // function getBase64<T extends string | ArrayBuffer | null>(file: File) {
  //   return new Promise<T>((resolve, reject) => {
  //     const reader = new FileReader();
  //     reader.readAsDataURL(file);
  //     reader.onload = () => {
  //       resolve(reader.result as T);
  //     };
  //     reader.onerror = (error) => reject(error);
  //   });
  // }

  const handlePreview = async (file: UploadFile) => {
    // if (!file.url && !file.preview) {
    //   file.preview = await getBase64<string>(file.originFileObj!);
    // }
    // previewImage.value = file.url || file.preview || '';
    // previewOpen.value = true;
    // previewTitle.value =
    //   file.name || previewImage.value.substring(previewImage.value.lastIndexOf('/') + 1);

    // const onImgLoad = ({ index, url, dom }) => {
    //   console.log(`第${index + 1}张图片已加载，URL为：${url}`, dom);
    // };
    // 可以使用createImgPreview返回的 PreviewActions 来控制预览逻辑，实现类似幻灯片、自动旋转之类的骚操作

    // let urlList = fileList.value.map((item) => {
    //   return item.url ? item.url : item.response.fileUrl;
    // });

    console.log('handlePreview', file.url || file.response[0].url);
    let fileUrl = '';
    if (props.uploadParams.batchId === 'null') {
      fileUrl = getFileUrl(file.url ? file : file.response[0]);
    } else {
      fileUrl = file.url || file.response[0].url;
    }

    console.log('fileUrl', fileUrl);
    const fileType = getFileType(fileUrl);
    console.log('fileType', fileType);

    // turn on preview
    switch (fileType) {
      case 'word':
        window.open(`https://view.officeapps.live.com/op/view.aspx?src=${file.url}`, '_blank');
        break;
      case 'excel':
        window.open(`https://view.officeapps.live.com/op/view.aspx?src=${file.url}`, '_blank');
        break;
      case 'pdf':
        window.open(file.url, '_blank');
        break;
      case 'image':
        createImgPreview({
          imageList: [fileUrl],
          defaultWidth: 700,
          rememberState: true,
        });
    }
  };

  const handleRemove = async (file: any) => {
    console.log('handleRemove', file);
    console.log('handleRemove-fileList', fileList);
    const { uploadParams = {} } = props;
    try {
      const remoreFiles = () => {
        if (file.id) {
          if (fileList.value) {
            const index = fileList.value.findIndex((item) => item.uid === file.uid);
            index !== -1 && fileList.value.splice(index, 1);
            const value = getValue();
            isInnerOperate.value = true;
            emit('update:value', value);
            emit('change', value);
            emit('delete', file);
          }
        }
      };
      if (uploadParams.batchId === 'null' || !uploadParams.batchId) {
        emit('delete', file);
        remoreFiles();
        return true;
      } else {
        const res = await delFileApi(file.id ? file.id : file.response.id);
        res && message.success('删除成功');
        remoreFiles();
        return !!res;
      }
    } catch (error) {
      message.error(error);
      return false;
    }
  };

  // const handleCancel = () => {
  //   previewOpen.value = false;
  //   previewTitle.value = '';
  // };

  const beforeUpload = (file: File) => {
    const { maxSize, accept } = props;
    const isAct = checkFileType(file, accept);
    if (!isAct) {
      createMessage.error(t('component.upload.acceptUpload', [accept]));
      isActMsg.value = false;
      // 防止弹出多个错误提示
      setTimeout(() => (isActMsg.value = true), 1000);
    }
    const isLt = file.size / 1024 / 1024 > maxSize;
    if (isLt) {
      createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
      isLtMsg.value = false;
      // 防止弹出多个错误提示
      setTimeout(() => (isLtMsg.value = true), 1000);
    }
    return (isAct && !isLt) || Upload.LIST_IGNORE;
  };

  async function customRequest(info: UploadRequestOption<any>) {
    // api,
    const { api, uploadParams = {}, name, filename, resultField } = props;
    // if (!api || !isFunction(api)) {
    //   return warn('upload api must exist and be a function');
    // }
    const requestApi = api || uploadApi;
    try {
      const res = await requestApi?.({
        ...uploadParams,
        file: info.file,
        name: name,
        filename: filename,
      });
      console.log('requestApi-res', res);
      if (props.resultField) {
        let result = get(res, resultField);
        info.onSuccess!(result);
      } else {
        // 不传入 resultField 的情况
        console.log('=============res.data', res);
        fileList.value = res;

        info.onSuccess!(res);
      }
      const value = getValue();
      isInnerOperate.value = true;
      console.log('update:vvalue', value);
      emit('update:value', value);
      emit('change', value);
    } catch (e: any) {
      console.log(e);
      info.onError!(e);
    }
  }

  function getValue() {
    console.log('getValue-fileList.value', fileList.value);
    const list = (fileList.value || [])
      .filter((item) => item?.status === UploadResultStatus.DONE)
      .map((item: any) => {
        if (item?.response && props?.resultField) {
          return item?.response;
        }

        if (item?.url) {
          return item;
        } else {
          return item?.response;
        }
      });
    return list;
  }
</script>

<style lang="less">
  .ant-upload-select-picture-card i {
    color: #999;
    font-size: 32px;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }
</style>
